package dcutils.rpg.stats;

// Import DCUtils Classes
import dcutils.Range;

/**
 * Represents a single character statistic like strength, defense, etc.
 * @author dca
 */
public class Stat extends Range<Integer> {
   private int id;        // unique identifier
   protected String name; // item name
   private int cur;       // current setting, must be within range

   public Stat(int cur, int max) throws RangeException {
      this(0, cur, max);
   } // END constructor
   public Stat(int min, int cur, int max) throws RangeException {
      this("", min, cur, max);
   } // END constructor
   public Stat(String name, int cur, int max) throws RangeException {
      this(name, 0, cur, max);
   } // END constructor
   public Stat(String name, int min, int cur, int max) throws RangeException {
      this((int)System.currentTimeMillis(), name, min, cur, max);
   } // END constructor
   public Stat(int id, String name, int cur, int max) throws RangeException {
      this(id, name, 0, cur, max);
   } // END constructor
   public Stat(int id, String name, int min, int cur, int max) throws RangeException {
      super(min, max);
      setId(id);
      setName(name);
      cur(cur);
      check();
   } // END constructor

   public int getId() {
      return id;
   } // END id getter
   public Stat setId(int id) {
      this.id = id;
      return this;
   } // END id setter

   public String getName() {
      return name;
   } // END name getter
   public Stat setName(String name) {
      this.name = name;
      return this;
   } // END name setter

   public int min() {
      return getBeginning();
   } // END min getter

   public Stat min(int num) throws RangeException {
      setBeginning(num);
      check();
      return this;
   } // END min setter

   public int cur() {
      return cur;
   } // END cur getter

   public Stat cur(int num) throws RangeException {
      this.cur = num;
      check();
      return this;
   } // END cur setter

   public int max() {
      return getEnding();
   } // END max getter

   public Stat max(int num) throws RangeException {
      setEnding(num);
      check();
      return this;
   } // END max setter

   public boolean increase() {
      if(cur() < max()) {
         cur++;
         return true;
      } else {
         return false;
      } // END if/else
   } // END increase

   private void check() throws RangeException {
      if(getBeginning() < 0) setBeginning(0);
      if(getEnding() < 1) setEnding(1);

      if(getBeginning() == getEnding()) setEnding(getBeginning() + 1);

      if(lessThanRange(cur, true)) cur = getBeginning();
      if(greaterThanRange(cur, true)) cur = getEnding();
   } // END check

   @Override
   public String toString() {
      if("".equals(name)) return String.valueOf(cur);
      else return String.format("%s: %s", name, cur);
   } // END toString

   @Override
   public boolean equals(Object obj) {
      if(null == obj) {
         return false;
      } else if(obj instanceof Stat) {
    	  Stat stat = (Stat)obj;

         return this.getName().equals(stat.getName()) &&
        		this.cur() == stat.cur();
      } else {
         return false;
      } // END if/else
   } // END equals

   @Override
   public int hashCode() {
      int hashCode = 101;
      hashCode = (11 * hashCode) + name.hashCode();
      hashCode = (11 * hashCode) + cur;
      return hashCode;
   } // END hashCode
} // END class Stat
